#include "storage/Page.h"

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

Page::Page(BufferManager* manager, Page* orgPage)
{
	bm = manager;
   
	pageSize = bm->GetPageSize();

	buffer = new char[pageSize];

    nodeID = bm->RequestID();

    bm->AddEntry(this, nodeID);

    page_mutex = PTHREAD_MUTEX_INITIALIZER;
}

Page::Page(const Page &p)
{
    bm = p.bm;
    
    pageSize = p.pageSize;
    
    buffer = new char[pageSize];

    nodeID = bm->RequestID();

    bm->AddEntry(this, nodeID);

    memcpy(buffer, p.buffer, pageSize);
    
	page_mutex = PTHREAD_MUTEX_INITIALIZER;
}

Page::~Page()
{
	if(isInMem)
	{
		delete [] buffer;
	}

    bm->RemoveEntry(nodeID);
}

bool Page::LoadFromFile()
{
	if(isInMem)
		return true;

	if(!buffer)
		buffer = new char[pageSize];
	else
	{
		cout << "loading error" << endl;
		//input.close();
		return false;
	}

	//input.read(buffer, pageSize);

	//input.close();

	if(!bm->readFromDisk(nodeID, buffer))
		cout << "reading error" << endl;

	bm->LoadUpdate(nodeID);

	isInMem = true;

	return true;
}

bool Page::SaveToFile()
{
	if(!isInMem)
		return false;

	if(bm->isDirty(nodeID))
	{
		bm->saveToDisk(nodeID, buffer);
	}

	isInMem = false;
	bm->SaveUpdate(nodeID);


	delete [] buffer;

	buffer = NULL;

	return true;
}

pthread_mutex_t* Page::LockPage()
{
    pthread_mutex_lock(&page_mutex);
    
    return &page_mutex;
}
